package com.zbkj.service.service.course.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.zbkj.common.constants.IntegralRecordConstants;
import com.zbkj.common.model.course.Course;
import com.zbkj.common.model.course.CourseCode;
import com.zbkj.common.model.course.UserTaskLog;
import com.zbkj.common.model.user.User;
import com.zbkj.common.model.user.UserIntegralRecord;
import com.zbkj.common.request.PageParamRequest;
import com.zbkj.common.request.course.CourseCodeSearchRequest;
import com.zbkj.common.request.course.QRCodeSweepRequest;
import com.zbkj.common.response.course.CourseCodeResponse;
import com.zbkj.common.utils.QRCodeUtil;
import com.zbkj.service.dao.CourseCodeDao;
import com.zbkj.service.service.UploadService;
import com.zbkj.service.service.UserIntegralRecordService;
import com.zbkj.service.service.UserService;
import com.zbkj.service.service.course.CourseCodeService;
import com.zbkj.service.service.course.CourseService;
import com.zbkj.service.service.impl.UserDetailServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;

/**
 * @author Mr.Zhang
 * @description CourseCodeServiceImpl 接口实现
 * @date 2022-07-22
 */
@Service
public class CourseCodeServiceImpl extends ServiceImpl<CourseCodeDao, CourseCode> implements CourseCodeService {
    private static final Logger log = LoggerFactory.getLogger(CourseCodeServiceImpl.class);

    @Resource
    private CourseCodeDao dao;

    @Autowired
    private CourseService courseService;

    @Autowired
    private UserService userService;

    @Autowired
    private UploadService uploadService;
    @Autowired
    private UserIntegralRecordService integralRecordService;

    @Autowired
    private ActivityLogServiceImpl activityLogService;
    /**
     * 列表
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return List<CourseCode>
     * @author Mr.Zhang
     * @since 2022-07-22
     */
    @Override
    public List<CourseCodeResponse> getList(CourseCodeSearchRequest request, PageParamRequest pageParamRequest) {
        PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());

        //带 CourseCode 类的多条件查询
        LambdaQueryWrapper<CourseCode> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        CourseCode model = new CourseCode();
        BeanUtils.copyProperties(request, model);
        lambdaQueryWrapper.setEntity(model);

        List<CourseCodeResponse> courseCodeResponses = new ArrayList<>();
        List<CourseCode> courseCodes = dao.selectList(lambdaQueryWrapper);
        if (CollectionUtil.isEmpty(courseCodes)) {
            return courseCodeResponses;
        }

        courseCodes.forEach(courseCode -> {
            CourseCodeResponse courseCodeResponse = new CourseCodeResponse();
            BeanUtil.copyProperties(courseCode, courseCodeResponse);
            //如果是积分二维码 就生成base64的编码
            if (ObjectUtil.isNotEmpty(request.getType()) && request.getType().equals(2)) {
                try {
                    courseCodeResponse.setQrCodeStr(QRCodeUtil.crateQRCode(courseCodeResponse.getCode(), 120, 120));
                } catch (IOException e) {
                    log.info("生成二维码报错");
                    throw new RuntimeException(e);
                }
            }
            courseCodeResponses.add(courseCodeResponse);

        });
        return courseCodeResponses;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public String generateCode(Integer courseId,Integer exchangeCount) {
        String code = createcode(8);
        LambdaQueryWrapper<CourseCode> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CourseCode::getCode, code);
        List<CourseCode> courseCodes = this.list(lambdaQueryWrapper);
        while (CollectionUtil.isNotEmpty(courseCodes)) {
            lambdaQueryWrapper.clear();
            code = createcode(8);
            lambdaQueryWrapper.eq(CourseCode::getCode, code);
            courseCodes = this.list(lambdaQueryWrapper);
        }
        CourseCode courseCode = new CourseCode();
        courseCode.setCode(code);
        courseCode.setStatus(false);
        courseCode.setCreateTime(new Date());
        courseCode.setCourseId(courseId);
        courseCode.setExchangeCount(ObjectUtil.isNull(exchangeCount)?1:exchangeCount);
        courseCode.setExchanged(0);
        courseCode.setLinkId(courseId);
        courseCode.setType(1);
        this.save(courseCode);

        LambdaUpdateWrapper<Course> courseLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        courseLambdaUpdateWrapper.setSql(StrUtil.format("code_count = code_count + {}", 1));
        courseLambdaUpdateWrapper.eq(Course::getId, courseId);
        courseService.update(courseLambdaUpdateWrapper);

        return code;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> generateCourseIntegralQRCode(Integer courseId, int count,int integral) throws IOException {
        List<String> integralQrCode = new ArrayList<>();
        List<CourseCode> courseCodes = new ArrayList<>();
        if(integral<=0){
            return integralQrCode;
        }
        for (int i = 0; i < count; i++) {
            String code = "plsk_jf_" + DateUtil.format(new Date(), "yyyy-MM-dd") + "_" + courseId + "_" + createcode(16);
            integralQrCode.add(QRCodeUtil.crateQRCode(code, 120, 120));
            CourseCode courseCode = new CourseCode();
            courseCode.setCode(code);
            courseCode.setStatus(false);
            courseCode.setCreateTime(new Date());
            courseCode.setCourseId(courseId);
            courseCode.setLinkId(courseId);
            courseCode.setCodeValue(integral);
            courseCode.setType(2);//"1：课程码，2课程积分二维码
            courseCodes.add(courseCode);
        }
        if (CollectionUtil.isNotEmpty(courseCodes)) {
            saveBatch(courseCodes);
            LambdaUpdateWrapper<Course> courseLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            courseLambdaUpdateWrapper.setSql(StrUtil.format("qr_code_count = qr_code_count + {}", courseCodes.size()));
            courseLambdaUpdateWrapper.eq(Course::getId, courseId);
            courseService.update(courseLambdaUpdateWrapper);
        }
        return integralQrCode;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String exchangeIntegralCode(String integralQRCode) {
        if (StringUtils.isEmpty(integralQRCode)) {
            return "编码不能为空";
        }
        if (!StringUtils.startsWith(integralQRCode, "plsk_jf")) {
            return "该二维码非派乐时刻积分兑换二维码";
        }
        LambdaQueryWrapper<CourseCode> lqw = new LambdaQueryWrapper<>();
        lqw.eq(CourseCode::getStatus, false);
        lqw.eq(CourseCode::getType, 2);
        lqw.eq(CourseCode::getCode, integralQRCode);
        List<CourseCode> courseCodes = this.list(lqw);
        if(CollectionUtil.isEmpty(courseCodes)){
            return "不存在该派乐时刻积分兑换二维码";
        }
        User user=userService.getInfoException();
        LambdaUpdateWrapper<CourseCode> uqw=new LambdaUpdateWrapper<>();
        uqw.eq(CourseCode::getCode,integralQRCode);
        uqw.set(CourseCode::getStatus,true);
        uqw.set(CourseCode::getUid,user.getUid());
        this.update(uqw);
        UserIntegralRecord integralRecord=integralRecordInit(courseCodes.get(0),user.getIntegral());
        integralRecordService.save(integralRecord);
        userService.operationIntegral(user.getUid(), courseCodes.get(0).getCodeValue()
                , user.getIntegral(), "add");
        return "积分二维码兑换成功，获得"+courseCodes.get(0).getCodeValue()+"积分";
    }

    /**
     *  生成活动签到码
     * @param linkedId
     * @return
     */
    @Override
    public String generateActivityQRCode(Integer linkedId, String beginDateStr
            ,String endDateStr,Integer integral) {
        String code = createcode(16);
        Date beginDate=DateUtil.parse(beginDateStr);
        Date endDate=DateUtil.parse(endDateStr);
        if(endDate.compareTo(beginDate)<=0){
            return "结束时间不能小于开始时间";
        }
        CourseCode courseCode = new CourseCode();
        courseCode.setCode(code);
        courseCode.setStatus(false);
        courseCode.setCreateTime(new Date());
        courseCode.setLinkId(linkedId);
        courseCode.setCodeValue(integral);
        courseCode.setType(3);//"1：课程码，2课程积分二维码3活动研学商品id
        courseCode.setBeginDate(beginDate);
        courseCode.setEndDate(endDate);
        return null;
    }


    @Override
    public Map<String, Object> sweepQRCode(QRCodeSweepRequest request) {
        Map<String,Object> data=new HashMap<>();
        if(StringUtils.isEmpty(request.getQrCodeStr())){
            data.put("success",false);
            data.put("message","二维码值不能为空");
            return data;
        }
        if(request.getQrCodeStr().startsWith("plsk_jf")){//积分兑换
            
            }  else if (request.getQrCodeStr().startsWith("plsk_qd")) {//活动签到
            return activityLogService.activitySign(request);
        }else {
            data.put("success",false);
            data.put("message","无效二维码");
        }
        return data;
    }

    private UserIntegralRecord integralRecordInit(CourseCode courseCode, Integer balance) {
        UserIntegralRecord integralRecord = new UserIntegralRecord();
        integralRecord.setUid(courseCode.getUid());
        integralRecord.setLinkId(courseCode.getId().toString());
        integralRecord.setLinkType(IntegralRecordConstants.INTEGRAL_RECORD_LINK_TYPE_QRCODE_INTEGRAL);
        integralRecord.setType(IntegralRecordConstants.INTEGRAL_RECORD_TYPE_ADD);
        integralRecord.setTitle(IntegralRecordConstants.BROKERAGE_RECORD_TITLE_TASK);
        integralRecord.setIntegral(courseCode.getCodeValue());
        integralRecord.setBalance(balance);
        integralRecord.setMark(StrUtil.format("用户商品积分二维码,订单增加{}积分", courseCode.getCodeValue()));
        integralRecord.setStatus(IntegralRecordConstants.INTEGRAL_RECORD_STATUS_COMPLETE);
        integralRecord.setFrozenTime(0);
        integralRecord.setCreateTime(com.zbkj.common.utils.DateUtil.nowDateTime());
        return integralRecord;
    }
    public static String createcode(int n) {
        //3.定义一个字符串变量记录生成的随机字符

        String code = "";
        Random r = new Random();
        //2.定义一个for循环，循环n次，依次生成随机字符串

        for (int i = 0; i < n; i++) {
            //3.生成一个随机字符，英文大写，小写，数字

            int type = r.nextInt(3);  //0,1,2类别

            switch (type) {
                case 0:
                    //大写字符（A 65--Z 65+25）(0-25)+65

                    char ch = (char) (r.nextInt(26) + 65);

                    code = code + ch;
                    break;


                case 1:
                    //小写字符（A 97--Z 97+25）(0-25)+97
                    char ch1 = (char) (r.nextInt(26) + 97);
                    code += ch1;
                    break;
                case 2:
                    // 数字字符
                    code += r.nextInt(10);
                    break;
            }
        }
        return code;
    }


}

